package io.netopen.hotbitmapgg.view;

import io.netopen.view.ResourceTable;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.Matrix;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.Resource;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import static ohos.agp.utils.TextAlignment.CENTER;

/**
 * Created by hcc on 16/9/2 19:28
 * 100332338@qq.com
 * <p/>
 * 新版芝麻信用圆环View
 */
public class NewCreditSesameView extends Component implements Component.DrawTask, Component.EstimateSizeListener,Component.BindStateChangedListener {

  // 圆环的信用等级文本
  String[] sesameStr = new String[] {
      "350", "较差",
      "550", "中等",
      "600", "良好",
      "650", "优秀",
      "700", "极好",
      "950"
  };

  // 默认宽高值
  private int defaultSize;

  // 距离圆环的值
  private int arcDistance;

  // view宽度
  private int width;

  // view高度
  private int height;

  // 默认Padding值
  private final static int defaultPadding = 20;

  //  圆环起始角度
  private final static float mStartAngle = 165f;

  // 圆环结束角度
  private final static float mEndAngle = 210f;

  //外层圆环画笔
  private Paint mMiddleArcPaint;

  //内层圆环画笔
  private Paint mInnerArcPaint;

  //信用等级文本画笔
  private Paint mTextPaint;

  //大刻度画笔
  private Paint mCalibrationPaint;

  //小刻度画笔
  private Paint mSmallCalibrationPaint;

  //小刻度画笔
  private Paint mCalibrationTextPaint;

  //进度圆环画笔
  private Paint mArcProgressPaint;

  //半径
  private int radius;

  //外层矩形
  private RectFloat mMiddleRect;

  //内层矩形
  private RectFloat mInnerRect;

  //进度矩形
  private RectFloat mMiddleProgressRect;

  // 最小数字
  private int mMinNum = 0;

  // 最大数字
  private int mMaxNum = 950;

  // 当前进度
  private float mCurrentAngle = 0f;

  //总进度
  private float mTotalAngle = 210f;

  //信用等级
  private String sesameLevel = "";

  //评估时间
  private String evaluationTime = "";

  //小圆点
  private PixelMap bitmap;

  //当前点的实际位置
  private float[] pos;

  //当前点的tangent值
  private float[] tan;

  //矩阵
  private Matrix matrix;

  //小圆点画笔
  private Paint mBitmapPaint;


  public NewCreditSesameView(Context context) {
    this(context, null);
  }


  public NewCreditSesameView(Context context, AttrSet attrs) {
    this(context, attrs, 0);
  }


  public NewCreditSesameView(Context context, AttrSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    addDrawTask(this);
    setEstimateSizeListener(this);
    setBindStateChangedListener(this);
    init(context);
  }


  /**
   * 初始化
   */
  private void init(Context context) {

    defaultSize = 250;
    arcDistance = 49;

    //外层圆环画笔
    mMiddleArcPaint = new Paint();
    mMiddleArcPaint.setStrokeWidth(8);
    mMiddleArcPaint.setColor(Color.WHITE);
    mMiddleArcPaint.setStyle(Paint.Style.STROKE_STYLE);
    mMiddleArcPaint.setAlpha(0.31f);

    //内层圆环画笔
    mInnerArcPaint = new Paint();
    mInnerArcPaint.setStrokeWidth(30);
    mInnerArcPaint.setColor(Color.WHITE);
    mInnerArcPaint.setAlpha(0.31f);
    mInnerArcPaint.setStyle(Paint.Style.STROKE_STYLE);

    //正中间字体画笔
    mTextPaint = new Paint();
    mTextPaint.setColor(Color.WHITE);
    mTextPaint.setTextAlign(CENTER);

    //圆环大刻度画笔
    mCalibrationPaint = new Paint();
    mCalibrationPaint.setStrokeWidth(4);
    mCalibrationPaint.setStyle(Paint.Style.STROKE_STYLE);
    mCalibrationPaint.setColor(Color.WHITE);
    mCalibrationPaint.setAlpha(0.47f);

    //圆环小刻度画笔
    mSmallCalibrationPaint = new Paint();
    mSmallCalibrationPaint.setStrokeWidth(1);
    mSmallCalibrationPaint.setStyle(Paint.Style.STROKE_STYLE);
    mSmallCalibrationPaint.setColor(Color.WHITE);
    mSmallCalibrationPaint.setAlpha(0.51f);

    //圆环刻度文本画笔
    mCalibrationTextPaint = new Paint();
    mCalibrationTextPaint.setTextSize(30);
    mCalibrationTextPaint.setColor(Color.WHITE);

    //外层进度画笔
    mArcProgressPaint = new Paint();
    mArcProgressPaint.setStrokeWidth(8);
    mArcProgressPaint.setColor(Color.WHITE);
    mArcProgressPaint.setStyle(Paint.Style.STROKE_STYLE);
    mArcProgressPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);

    mBitmapPaint = new Paint();
    mBitmapPaint.setStyle(Paint.Style.FILL_STYLE);
    mBitmapPaint.setAntiAlias(true);

    //初始化小圆点图片
    bitmap =getPixelMap(context, ResourceTable.Media_circle);
    pos = new float[2];
    tan = new float[2];
    matrix = new Matrix();

  }
  /**
   * To load PixelMap from resource file
   *
   * @param context Context
   * @param id      Resource ID
   * @return PixelMap
   */
  public static PixelMap getPixelMap(Context context, int id) {
    ImageSource.SourceOptions options = new ImageSource.SourceOptions();
    options.formatHint = "image/png";
    ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
    try {
      Resource asset = context.getResourceManager().getResource(id);
      ImageSource source = ImageSource.create(asset, options);
      return source.createPixelmap(decodingOptions);
    } catch (IOException | NotExistException e) {
      //LogUtil.error(AttrUtils.class.getName(), e.getMessage());
    }
    return null;
  }

  /**
   * 根据传入的值进行测量
   */
  public int resolveMeasure(int measureSpec, int defaultSize) {

    int result = 0;
    int specSize = EstimateSpec.getSize(measureSpec);
    switch (EstimateSpec.getMode(measureSpec)) {

      case EstimateSpec.UNCONSTRAINT:
        result = defaultSize;
        break;

      case EstimateSpec.NOT_EXCEED:
        //设置warp_content时设置默认值
        result = Math.min(specSize, defaultSize);
        break;
      case EstimateSpec.PRECISE:
        //设置math_parent 和设置了固定宽高值
        break;

      default:
        result = defaultSize;
    }

    return result;
  }

  @Override
  public boolean onEstimateSize(int i, int i1) {
    //setEstimatedSize(resolveMeasure(i, defaultSize),resolveMeasure(i1,defaultSize));
    return false;
  }

  @Override
  public void onComponentUnboundFromWindow(Component component) {

  }
  @Override
  public void onComponentBoundToWindow(Component component) {

    width = getWidth();
    height = getHeight();


    mMiddleRect = new RectFloat(
        defaultPadding, defaultPadding,
        width - defaultPadding, height - defaultPadding);

    mInnerRect = new RectFloat(
        defaultPadding + arcDistance,
        defaultPadding + arcDistance,
        width - defaultPadding - arcDistance,
        height - defaultPadding - arcDistance);

    mMiddleProgressRect = new RectFloat(
        defaultPadding, defaultPadding,
        width - defaultPadding, height - defaultPadding);

    radius = width / 2;
  }


  @Override
  public void onDraw(Component component, Canvas canvas) {
    drawMiddleArc(canvas);//进度背景
    drawInnerArc(canvas);//大白条背景
    drawSmallCalibration(canvas);//小刻度绘制
    drawCalibrationAndText(canvas);//刻度分小字
    drawCenterText(canvas);//中间大字
    drawRingProgress(canvas);//进度
  }


  /**
   * 绘制内层小刻度
   */
  private void drawSmallCalibration(Canvas canvas) {
    //旋转画布
    canvas.save();
    canvas.rotate(-105, radius, radius);
    //计算刻度线的起点结束点
    int startDst = (int) (defaultPadding + arcDistance - mInnerArcPaint.getStrokeWidth() / 2 - 1);
    int endDst = (int) (startDst + mInnerArcPaint.getStrokeWidth());
    for (int i = 0; i <= 35; i++) {
      //每旋转6度绘制一个小刻度
      canvas.drawLine(radius, startDst, radius, endDst, mSmallCalibrationPaint);
      canvas.rotate(6, radius, radius);
    }
    canvas.restore();
  }

  private static PixelMap createPixelMap(int width, int height) {

    PixelMap pixelMap;

    PixelMap.InitializationOptions options =

            new PixelMap.InitializationOptions();

    options.size = new Size(width, height);

    options.pixelFormat = PixelFormat.ARGB_8888;

    options.editable = true;

    pixelMap = PixelMap.create(options);

    return pixelMap;

  }
  /**
   * 绘制外层圆环进度和小圆点
   */
  private void drawRingProgress(Canvas canvas) {

    Path path = new Path();
    path.addArc(mMiddleProgressRect, mStartAngle, mCurrentAngle);
    PathMeasure pathMeasure = new PathMeasure(path, false);
    pathMeasure.getPosTan(pathMeasure.getLength() * 1, pos, tan);
    matrix.reset();
    matrix.postTranslate(pos[0] - bitmap.getImageInfo().size.width / 2, pos[1] - bitmap.getImageInfo().size.height / 2);
    canvas.drawPath(path, mArcProgressPaint);
//起始角度不为0时候才进行绘制小圆点
    if (mCurrentAngle == 0) {
      return;
    }
    mBitmapPaint.setColor(Color.WHITE);
    canvas.drawCircle(pos[0], pos[1], 8, mBitmapPaint);
  }


  /**
   * 绘制中间文本
   */
  private void drawCenterText(Canvas canvas) {
    //绘制Logo
    mTextPaint.setTextSize(30);
    canvas.drawText(mTextPaint,"BETA", radius, radius - 130);

    //绘制信用分数
    mTextPaint.setTextSize(200);
    mTextPaint.setStyle(Paint.Style.FILL_STYLE);
    canvas.drawText(mTextPaint,String.valueOf(mMinNum), radius, radius + 70);

    //绘制信用级别
    mTextPaint.setTextSize(80);
    canvas.drawText(mTextPaint,sesameLevel, radius, radius + 160);

    //绘制评估时间
    mTextPaint.setTextSize(30);
    canvas.drawText(mTextPaint,evaluationTime, radius, radius + 205);
  }


  /**
   * 绘制刻度
   */
  private void drawCalibrationAndText(Canvas canvas) {
    //旋转画布进行绘制对应的刻度
    canvas.save();
    canvas.rotate(-105, radius, radius);
    //计算刻度线的起点结束点
    int startDst = (int) (defaultPadding + arcDistance - mInnerArcPaint.getStrokeWidth() / 2 - 1);
    int endDst = (int) (startDst + mInnerArcPaint.getStrokeWidth());
    //刻度旋转的角度
    int rotateAngle = 210 / 10;
    for (int i = 1; i < 12; i++) {
      if (i % 2 != 0) {
        canvas.drawLine(radius, startDst, radius, endDst, mCalibrationPaint);
      }
      // 测量文本的长度
      float textLen = mCalibrationTextPaint.measureText(sesameStr[i - 1]);
      canvas.drawText(mCalibrationTextPaint,sesameStr[i - 1], radius - textLen / 2, endDst + 40);
      canvas.rotate(rotateAngle, radius, radius);
    }

    canvas.restore();
  }


  /**
   * 绘制内层圆环
   */
  private void drawInnerArc(Canvas canvas) {

    canvas.drawArc(mInnerRect, new Arc(mStartAngle, mEndAngle, false), mInnerArcPaint);
  }


  /**
   * 绘制外层圆环
   */
  private void drawMiddleArc(Canvas canvas) {

    canvas.drawArc(mMiddleRect, new Arc(mStartAngle, mEndAngle, false), mMiddleArcPaint);
  }





  public void setSesameValues(int values) {

    if (values <= 350) {
      mMaxNum = values;
      mTotalAngle = 0f;
      sesameLevel = "信用较差";
      evaluationTime = "评估时间:" + getCurrentTime();
    } else if (values <= 550) {
      mMaxNum = values;
      mTotalAngle = (values - 350) * 80 / 400f + 2;
      sesameLevel = "信用较差";
      evaluationTime = "评估时间:" + getCurrentTime();
    } else if (values <= 700) {
      mMaxNum = values;
      if (values > 550 && values <= 600) {
        sesameLevel = "信用中等";
        mTotalAngle = (values - 550) * 120 / 150f + 43;
      } else if (values > 600 && values <= 650) {
        sesameLevel = "信用良好";
        mTotalAngle = (values - 550) * 120 / 150f + 45;
      } else {
        sesameLevel = "信用优秀";
        mTotalAngle = (values - 550) * 120 / 150f + 48;
      }
      evaluationTime = "评估时间:" + getCurrentTime();
    } else if (values <= 950) {
      mMaxNum = values;
      mTotalAngle = (values - 700) * 40 / 250f + 170;
      sesameLevel = "信用极好";
      evaluationTime = "评估时间:" + getCurrentTime();
    } else {
      mTotalAngle = 240f;
    }

    startAnim();
  }

  boolean b;
  float d;
  float startAngle;
  int startNum;
  int dNum;
  public void startAnim() {
    startAngle=mCurrentAngle;
    if(mCurrentAngle<mTotalAngle){
      b=true;
      d=mTotalAngle-mCurrentAngle;
    }else{
      b=false;
      d=mCurrentAngle-mTotalAngle;
    }
    AnimatorValue mAngleAnim = new AnimatorValue();
    mAngleAnim.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
    mAngleAnim.setDuration(3000);
    mAngleAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
      @Override
      public void onUpdate(AnimatorValue animatorValue, float v) {//0-1
        if(b){
          mCurrentAngle =startAngle+d*v;
        }else{
          mCurrentAngle =startAngle-d*v;
        }

        invalidate();
      }
    });
    mAngleAnim.start();
    startNum=mMinNum;
    // mMinNum = 350;
    if(mMinNum<mMaxNum){
      b=true;
      dNum=mMaxNum-mMinNum;
    }else{
      b=false;
      dNum=mMinNum-mMaxNum;
    }
    AnimatorValue mNumAnim = new AnimatorValue();
    mNumAnim.setDuration(3000);
    mNumAnim.setCurveType(Animator.CurveType.LINEAR);
    mNumAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
      @Override
      public void onUpdate(AnimatorValue animatorValue, float v) {
        if(b){
          mMinNum =startNum+(int)(dNum*v);
        }else{
          mMinNum =startNum-(int)(dNum*v);
        }

        invalidate();
      }
    });
    mNumAnim.start();
  }




  /**
   * 获取当前时间
   */
  public String getCurrentTime() {
    SimpleDateFormat format = new SimpleDateFormat("yyyy:MM:dd");
    return format.format(new Date());
  }
}
